package com.example.service.utils;

import com.example.entity.shop.SellerProduct;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import org.ansj.domain.Term;
import org.ansj.splitWord.analysis.ToAnalysis;

/**
 * 推荐词工具
 */
@Service
public class ProductDescriptionMatcher {

    // 计算商品描述相似度
    public List<SellerProduct> findMostSimilarProducts(String inputDescription, List<SellerProduct> productList) {
        // 输入的描述向量化
        Map<String, Integer> inputVector = getTFIDFVector(inputDescription);

        // 计算每个商品描述的相似度
        return productList.stream()
                .map(product -> {
                    Map<String, Integer> productVector = getTFIDFVector(product.getDescription());
                    double similarity = computeCosineSimilarity(inputVector, productVector);  // 使用余弦相似度
                    product.setSimilarity(similarity); // 设置相似度
                    return product;
                })
                .sorted((p1, p2) -> Double.compare(p2.getSimilarity(), p1.getSimilarity())) // 按相似度排序
                .limit(3) // 取前3个最相似的商品
                .collect(Collectors.toList());
    }

    // 使用 ansj_seg 进行中文分词，计算 TF-IDF 向量
    private Map<String, Integer> getTFIDFVector(String text) {
        Map<String, Integer> vector = new HashMap<>();
        // 使用 ansj_seg 对文本进行分词
        List<Term> terms = ToAnalysis.parse(text).getTerms();  // 获取分词结果
        for (Term term : terms) {
            String word = term.getName();  // 提取词语
            vector.put(word, vector.getOrDefault(word, 0) + 1);
        }
        return vector;
    }

    // 计算余弦相似度
    private double computeCosineSimilarity(Map<String, Integer> vector1, Map<String, Integer> vector2) {
        Set<String> allWords = new HashSet<>(vector1.keySet());
        allWords.addAll(vector2.keySet());

        double dotProduct = 0;
        double magnitude1 = 0;
        double magnitude2 = 0;

        for (String word : allWords) {
            int count1 = vector1.getOrDefault(word, 0);
            int count2 = vector2.getOrDefault(word, 0);

            dotProduct += count1 * count2;
            magnitude1 += count1 * count1;
            magnitude2 += count2 * count2;
        }

        return dotProduct / (Math.sqrt(magnitude1) * Math.sqrt(magnitude2));  // 余弦相似度公式
    }
}

